1W - 네이티브 사이드카 컨테이너 이용
개요
1주차에 마지막으로 해볼 실습은 쿠버네티스 네이티브 사이드카 컨테이너 활용이다.
쿠버네티스 최신 버전에서는 사이드카 컨테이너 기능을 제공한다.
그리고 이스티오에서도 이 사이드카를 그대로 사용할 수 있다.[^11]
사전 지식
사이드카 컨테이너란
기본적으로 사이드카 컨테이너는 사이드카 패턴을 컨테이너 형태로 만든 것을 말한다.
공식 문서에서는 사이드카 컨테이너라고 페이지를 아예 하나 빼서 설명하지만, 아예 sidecarContainer
이런 식으로 별도의 스펙이 만들어진 것은 아니라는 점을 유념할 필요가 있다.
사이드카 컨테이너는 메인 컨테이너들의 옆에 꼭 달라붙어 로깅, 프록시 등의 보조적인 기능을 수행하는 컨테이너를 일컫는 표현일 뿐이다.
1.28 버전 이후로부터 쿠버네티스에서는 자체적으로 사이드카 구현 방식을 제공하고 있다.
초기화 컨테이너에 restartPolicy
를 Always로 걸어서 만드는 방식으로..
이 문서에서 설명하는 사이드카 컨테이너는 바로 이 쿠버네티스 네이티브 사이드카 컨테이너이다.
엄밀한 구조로 보자면 초기화 컨테이너의 한 종류이며, 이 글에서 언급할 초기화 컨테이너는 사이드카 컨테이너가 아닌 초기화 컨테이너를 한정하여 표현한다.
기능
일단 사이드카 패턴 자체는, 비즈니스 로직을 담당하는 프로세스와 별개로 보조적인 기능을 하는 프로세스를 둘 때 사용한다.
대표적으로 다음의 기능들을 위해 패턴을 활용할 수 있겠다.
- 관측 가능성
- 로깅, 메트릭, 트레이싱 등의 기능을 비즈니스 로직으로부터 분리하여 제공
- 헬스체크
- 컨테이너 프로브보다 훨씬 복잡한 헬스체크 로직을 넣거나, 실제 트래픽 기반으로 상태를 확인할 때
- 동적 설정
- 클러스터 수준에서 어플리케이션 설정을 하면서 이것이 동적으로 컨테이너에 반영하게 하고 싶을 때.
- 앱 프로세스가 반드시 재시작해야 설정이 적용된다면 일찌감치 config-reloader라 해서 앱 프로세스를 재시작하는 별도의 프로세스를 구축해두는 것이 가능하다.
앱 컨테이너 상위의 라이프사이클
사이드카 패턴을 왜 쓰는지는 알겠고, 그래서 쿠버네티스 네이티브 사이드카 컨테이너는 왜 쓰는가?
파드에는 여러 개의 컨테이너를 둘 수 있으니, 그냥 따로 컨테이너를 하나 더 설정하여 위의 기능들을 충족하는 컨테이너를 두는 것이 가능하다.
사이드카 컨테이너의 가장 큰 장점은, 사이드카 컨테이너가 파드의 전체 생애 주기와 함께 한다는 것에 있다.
일반적인 방식으로 컨테이너를 설정하는 방식에서 발생할 수 있는 상황을 짚어보자.
- 메인 앱 로직을 담당하는 컨테이너보다 늦게 실행될 수 있다.
- 결국 모든 컨테이너가 실행은 되겠지만, 뭐가 먼저 시작될지는 쿠버 조상님도 모른다.
- 여차하면 앱이 실행되고 한참 뒤에야 로깅이 가능할 수도 있다는 것이다..
- 파드 종료 시 앱 컨테이너보다 먼저 종료될 수 있다.
- 앱 컨테이너가 종료되는 과정에도 사이드카 프로세스가 동작해야 할 수 있는데, 일반 컨테이너 방식으로는 이걸 보장하기 어렵다.
- 컨테이너의 프로브가 파드 전체에 영향을 준다.
- 앱 로직 컨테이너는 멀쩡한데 사이드카로 쓰는 컨테이너의 readiness에 문제가 생긴다고 해보자.
- 그럼 앱 자체는 정상 작동하는데도 해당 파드로 트래픽이 오지 않게 되는 불상사가 일어날 수 있다.
사이드카 컨테이너는 완벽하게 파드와 라이프사이클을 함께 하며, 앱 컨테이너에 영향이 가지 않는 것이 보장된다!
일단 초기화 컨테이너로서 앱 컨테이너보다 먼저 실행되는 것이 완벽하게 보장된다.
나름 초기화 컨테이너이기 때문에 사이드카 컨테이너가 종료되는 불상사가 있다면 앱 컨테이너는 절대 시작되지 않는다.
또한 파드가 성공이나 실패를 통해 종료된다 해도 사이드카 컨테이너는 메인 컨테이너가 종료되기 이전까지는 무조건 기능한다.
여기에 사이드카 컨테이너의 프로브는 절대 파드 전체에 영향을 주지 않는다!
이것이 사이드카 컨테이너를 사용하는 핵심 이유 되시겠다.
사이드카로 데이터 플레인을 구성하는 이스티오에서도 이 네이티브 사이드카 컨테이너를 이용한 설정 방법을 제공해주고 있다.
예시
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
template:
spec:
containers:
- name: myjob
image: alpine:latest
command: ['sh', '-c', 'echo "logging" > /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
initContainers:
- name: logshipper
image: alpine:latest
restartPolicy: Always
command: ['sh', '-c', 'tail -F /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
restartPolicy: Never
volumes:
- name: data
emptyDir: {}
사이드카 컨테이너의 진미가 드러나는 예시.
잡은 종료가 보장되는 앱 컨테이너를 두고 사용하는 리소스인데 여기에 위처럼 로깅 설정을 한다면!
위처럼 로깅 기능을 하는 컨테이너랑 상관 없이 잡이 종료되도록 보장하는 것이 중요한데 이럴 때 사이드카 컨테이너가 매우 유용하다!
이 덕분에, 파드의 생애 주기 자체에 영향을 조금도 주지 않으면서 생애 주기를 함께 하는 컨테이너를 만들 수 있게 되는 것이다.
실습 진행
이제 이 갓벽한 사이드카 컨테이너로 데이터 플레인의 엔보이가 설정되도록 만들어보자.
이스티오 설정
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: demo
components:
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
service:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30000
externalTrafficPolicy: Local
egressGateways:
- name: istio-egressgateway
enabled: false
meshConfig:
defaultProviders:
metrics:
- prometheus
tracing: []
values:
pilot:
env:
ENABLE_NATIVE_SIDECARS: true
istio operator에서 헬름 values 파일에 넣는 설정을 넣는 필드가 있다.
여기에 values.pilot.env
에 설정값을 넣어주면 된다.
istioctl upgrade -f initstio.yaml
업그레이드를 하고, 샘플 파일을 재기동 해준다.
기본 상태를 보면 별 차이가 없어보인다.
그러나 막상 container 부분에는 하나의 컨테이너만 띄워져 있는 것이 보인다!
Init Containers:
istio-init:
Image: docker.io/istio/proxyv2:1.25.1
...
State: Terminated
Reason: Completed
Exit Code: 0
Started: Thu, 10 Apr 2025 19:16:39 +0900
Finished: Thu, 10 Apr 2025 19:16:39 +0900
Ready: True
Restart Count: 0
istio-proxy:
Image: docker.io/istio/proxyv2:1.25.1
Port: 15090/TCP
Host Port: 0/TCP
Args:
proxy
sidecar
--domain
$(POD_NAMESPACE).svc.cluster.local
--proxyLogLevel=warning
--proxyComponentLogLevel=misc:error
--log_output_level=default:info
State: Running
Started: Thu, 10 Apr 2025 19:16:40 +0900
Ready: True
Readiness: http-get http://:15021/healthz/ready delay=0s timeout=3s period=15s #success=1 #failure=4
Startup: http-get http://:15021/healthz/ready delay=0s timeout=3s period=1s #success=1 #failure=600
...
init container 쪽을 보면, 기존에 컨테이너 쪽에서 돌아가던 프록시 컨테이너가 들어있는 것을 볼 수 있다.
어디에 설정됐냐 해서 실제 동작에서 달라지는 것은 없다.
다만 이제 이 프록시는 명확하게 앱 컨테이너가 실행되기 이전에 실행되고, 종료될 때도 앱 컨테이너 종료 이후에 종료되는 것이 보장된다.
그래서 파드 실행 간에 미연의 오작동을 원천 봉쇄할 수 있게 된다.
결론
위에서 봤듯이, 사이드카 컨테이너로서 활용할 프로세스가 있다면 이제 쿠버네티스 네이티브 사이드카 컨테이너를 활용하는 게 좋다.
솔직히 쓰고 안 쓰고 트레이드오프를 비교할 거리도 없이 사이드카 패턴을 사용하는 이상 안 쓸 이유가 그다지 없다고 생각한다.
그럴 일이야 있겠냐마는 막말로 엔보이 프록시가 뜨기 이전에 앱 컨테이너가 기동이 돼서 애매한 오작동이 생길 여지를 남길 바에는 안전하게 네이티브 사이드카 츄라이츄라이
(쿠버 1.28 버전 미만이라면, 피쳐게이트에서 기능을 반드시 활성화해야 한다!)
막간 실험
실습을 하다가 두 가지를 실험해보고 싶어졌다.
- 내가 먼저 istio-proxy라는 이름의 컨테이너를 만들어버리면 어떻게 되나?
- 엔보이 포트를 내가 먼저 가져가면 어떻게 되나?
이런 케이스에 대해서 당연히 검증 에러를 내뿜거나, 알아서 다른 포트를 설정하도록 자동화를 해두었을 것이라 생각하지만 그래도 궁금한 건 참을 수 없다.
apiVersion: v1
kind: Pod
metadata:
name: bad-pod
labels:
role: bad-pod
spec:
containers:
- name: istio-proxy
image: nginx:1.21
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
- containerPort: 15001
protocol: TCP
대놓고 멀쩡한 이스티오 데이터 플레인 설정을 괴롭히기 위해 컨테이너 이름과 포트를 점유하는 아주 못된 파드다.
(아직 goland로 보는 게 익숙치 않은 이슈)
컨테이너 로그에다 이벤트 로그까지 한꺼번에 보여주고 있는 것 같은데, 이건 나중에 조금 더 파보기로 하고, 아무튼 문제가 발생한 상황을 볼 수 있다.
나는 당연히 istio-proxy라는 이름을 먼저 써버리면 승인 웹훅을 통해 검증 에러를 내줄 거라 생각했는데, 단순하게 변형 웹훅만 걸려있는 것으로 보인다.
원래는 내가 만든 컨테이너와 변형 웹훅을 통해 주입된 컨테이너로 2개의 컨테이너가 떠야 정상이나, 내 예상과 다르게 그냥 내가 설정한 컨테이너에 덮어씌우기를 시전했다;;
이스티오 일해라
사실 누가 컨테이너 이름을 istio-proxy로 하겠냐마는.. 검증 웹훅을 통해 휴먼 에러를 막는 로직이 있으면 좋겠다는 생각은 든다.
apiVersion: v1
kind: Pod
metadata:
name: bad-pod
labels:
role: bad-pod
spec:
containers:
- name: istio
image: docker.io/istio/proxyv2:1.25.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
- containerPort: 15001
protocol: TCP
- containerPort: 15006
protocol: TCP
이번에는 이름은 그대로 두고, 이미지를 아예 변경했다.
사실 파드 양식에 포트를 설정하는 것은 어차피 실제 프로세스에 아무런 영향을 주지 않는다.
그냥 클러스터 내에서 포트 매핑을 빠르게 하기 위해 가시성 작업에 지나지 않고, 끽해야 포트 이름 설정 정도.
사용되는 이미지가 해당 포트를 사용하고 있을 때만 같은 네트워크 상에서 포트가 바인딩됐다던가 하는 에러가 나올 것이다.
그래서 아예 주입되는 컨테이너 이미지를 내가 먼저 넣어봤다.
이번에도 에러가 발생한다.
이 에러는 뭔가 했는데, 그냥 단순히 인자를 전달하지 않고 이미지를 사용하여 컨테이너가 완료돼서 크룹백에 빠진 이슈였다.
초기화 컨테이너의 설정에는 아무런 변화가 발생하지 않았다.
istio-proxy라는 컨테이너 이름을 사용하는 실무 케이스는 절대 흔하지 않을 것이라 생각하고 그래서 저런 부분에 대한 이슈 대응이 크게 필요하지 않다고 생각한다.
그런데 포트는 조금 더 엄밀하게 제한을 둬야 하는 걸 필요성이 있지 않을까 싶기도 하다.
15001, 15006 포트가 well-known 포트마냥 전세계적으로 잘 알려진 이스티오 전용 포트라도 되는 건가?
설령 그렇다고 해도 해당 포트를 사용하는 어플리케이션이 있다면 이에 대한 경고나 에러를 사전에 띄우는 식으로라도 제한을 걸어둬야 디버깅에 도움이 될 것 같다.
아무튼 어거지로 이스티오 괴롭히기 실험이었지만, 생각보다 사이드카 설정이 경직돼있다는 것을 알 수 있었다..
아마 추후에 데이터 플레인 설정 방법을 조금 더 파다보면 이런 것들도 커스텀하는 방법이 있을지도 모르겠다.
이전 글, 다음 글
다른 글 보기
이름 | index | noteType | created |
---|---|---|---|
1W - 서비스 메시와 이스티오 | 1 | published | 2025-04-10 |
1W - 간단한 장애 상황 구현 후 대응 실습 | 2 | published | 2025-04-10 |
1W - Gateway API를 활용한 설정 | 3 | published | 2025-04-10 |
1W - 네이티브 사이드카 컨테이너 이용 | 4 | published | 2025-04-10 |
2W - 엔보이 | 5 | published | 2025-04-19 |
2W - 인그레스 게이트웨이 실습 | 6 | published | 2025-04-17 |
3W - 버츄얼 서비스를 활용한 기본 트래픽 관리 | 7 | published | 2025-04-22 |
3W - 트래픽 가중치 - flagger와 argo rollout을 이용한 점진적 배포 | 8 | published | 2025-04-22 |
3W - 트래픽 미러링 패킷 캡쳐 | 9 | published | 2025-04-22 |
3W - 서비스 엔트리와 이그레스 게이트웨이 | 10 | published | 2025-04-22 |
3W - 데스티네이션 룰을 활용한 네트워크 복원력 | 11 | published | 2025-04-26 |
3W - 타임아웃, 재시도를 활용한 네트워크 복원력 | 12 | published | 2025-04-26 |
4W - 이스티오 메트릭 확인 | 13 | published | 2025-05-03 |
4W - 이스티오 메트릭 커스텀, 프로메테우스와 그라파나 | 14 | published | 2025-05-03 |
4W - 오픈텔레메트리 기반 트레이싱 예거 시각화, 키알리 시각화 | 15 | published | 2025-05-03 |
4W - 번외 - 트레이싱용 심플 메시 서버 개발 | 16 | published | 2025-05-03 |
5W - 이스티오 mTLS와 SPIFFE | 17 | published | 2025-05-11 |
5W - 이스티오 JWT 인증 | 18 | published | 2025-05-11 |
5W - 이스티오 인가 정책 설정 | 19 | published | 2025-05-11 |
6W - 이스티오 설정 트러블슈팅 | 20 | published | 2025-05-18 |
6W - 이스티오 컨트롤 플레인 성능 최적화 | 21 | published | 2025-05-18 |
8W - 가상머신 통합하기 | 22 | published | 2025-06-01 |
8W - 엔보이와 iptables 뜯어먹기 | 23 | published | 2025-06-01 |
9W - 앰비언트 모드 구조, 원리 | 24 | published | 2025-06-07 |
9W - 앰비언트 헬름 설치, 각종 리소스 실습 | 25 | published | 2025-06-07 |
7W - 이스티오 메시 스케일링 | 26 | published | 2025-06-09 |
7W - 엔보이 필터를 통한 기능 확장 | 27 | published | 2025-06-09 |
관련 문서
이름 | noteType | created |
---|---|---|
사이드카 컨테이너 | knowledge | 2024-08-22 |
1W - 네이티브 사이드카 컨테이너 이용 | published | 2025-04-10 |
E-초기화 컨테이너보다 앞서는 사이드카 컨테이너 | topic/explain | 2024-08-30 |